@using Microsoft.JSInterop
@using Nethereum.Wallet.UI.Components.Services
@using Nethereum.Wallet.UI.Components.Blazor.Shared
@using Nethereum.Wallet.UI.Components.Core.Localization
@using Nethereum.Wallet.UI.Components.Prompts
@using Nethereum.Wallet.UI.Components.Blazor.Prompts
@using MudBlazor
@using Nethereum.Wallet.Diagnostics
@inject IComponentLocalizer<DAppSignaturePromptView> Localizer
@inject DAppSignaturePromptViewModel ViewModel
@inject IJSRuntime JSRuntime

<WalletFormLayout Title="@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.Title)"
                  Subtitle="@GetSubtitle()"
                  ExitText="@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.Reject)"
                  ShowPrimary="true"
                  PrimaryText="@(ViewModel.SignatureReady ? Localizer.GetString(DAppSignaturePromptLocalizer.Keys.ConfirmSignature) : Localizer.GetString(DAppSignaturePromptLocalizer.Keys.Sign))"
                  OnExit="HandleReject"
                  OnPrimary="HandleSign"
                  PrimaryDisabled="@ViewModel.IsSigning">
    
    <ChildContent>
        @if (SignatureInfo != null)
        {
            <WalletFormSection Title="@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.RequestDetails)">
            @if (SignatureInfo != null && !string.IsNullOrEmpty(SignatureInfo.DAppName))
            {
                <WalletInfoCard Icon="@Icons.Material.Filled.Apps"
                                Title="@SignatureInfo.DAppName"
                                Description="@SignatureInfo.Origin" />
            }

            @if (!string.IsNullOrEmpty(SignatureInfo?.Address))
            {
                <MudAlert Severity="Severity.Info" Class="mt-3">
                    <MudText Typo="Typo.body2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.AccountDisplay, SignatureInfo.Address)</MudText>
                </MudAlert>
            }

            @if (!string.IsNullOrEmpty(SignatureInfo?.Method))
            {
                <MudChip T="string" Size="Size.Small" Color="Color.Primary" Class="mt-2">@SignatureInfo.Method</MudChip>
            }

            @if (SignatureInfo?.Method == "eth_signTypedData_v4")
            {
                <MudPaper Class="pa-3 mt-3" Elevation="1">
                    <MudStack Spacing="1">
                        <MudText Typo="Typo.subtitle2" FontWeight="FontWeight.Bold">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.DomainSectionTitle)</MudText>

                        @if (!string.IsNullOrEmpty(SignatureInfo.DomainName))
                        {
                            <MudText Typo="Typo.caption" Color="Color.Secondary">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.DomainName)</MudText>
                            <MudText Typo="Typo.body2">@SignatureInfo.DomainName</MudText>
                        }

                        @if (!string.IsNullOrEmpty(SignatureInfo.DomainVersion))
                        {
                            <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.DomainVersion)</MudText>
                            <MudText Typo="Typo.body2">@SignatureInfo.DomainVersion</MudText>
                        }

                        @if (!string.IsNullOrEmpty(SignatureInfo.VerifyingContract))
                        {
                            <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.VerifyingContract)</MudText>
                            <MudText Typo="Typo.body2">@SignatureInfo.VerifyingContract</MudText>
                        }

                        @if (!string.IsNullOrEmpty(SignatureInfo.PrimaryType))
                        {
                            <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.PrimaryType)</MudText>
                            <MudText Typo="Typo.body2">@SignatureInfo.PrimaryType</MudText>
                        }

                        @if (!string.IsNullOrEmpty(SignatureInfo.ChainId))
                        {
                            <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.ChainId)</MudText>
                            <MudText Typo="Typo.body2">@SignatureInfo.ChainId</MudText>
                        }
                    </MudStack>
                </MudPaper>

                @if (ViewModel.HasTypedDataHashes)
                {
                    <MudPaper Class="pa-3 mt-3" Elevation="1">
                        <MudStack Spacing="1">
                            <MudText Typo="Typo.subtitle2" FontWeight="FontWeight.Bold">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.HashSectionTitle)</MudText>
                            @if (!string.IsNullOrEmpty(ViewModel.TypedDataDomainHash))
                            {
                                <MudText Typo="Typo.caption" Color="Color.Secondary">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.DomainHashLabel)</MudText>
                                <MudText Typo="Typo.body2" Style="font-family: var(--mud-typography-body2-font-family, monospace); word-break: break-all;">@ViewModel.TypedDataDomainHash</MudText>
                            }
                            @if (!string.IsNullOrEmpty(ViewModel.TypedDataMessageHash))
                            {
                                <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.MessageHashLabel)</MudText>
                                <MudText Typo="Typo.body2" Style="font-family: var(--mud-typography-body2-font-family, monospace); word-break: break-all;">@ViewModel.TypedDataMessageHash</MudText>
                            }
                            @if (!string.IsNullOrEmpty(ViewModel.TypedDataHash))
                            {
                                <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.TypedDataHashLabel)</MudText>
                                <MudText Typo="Typo.body2" Style="font-family: var(--mud-typography-body2-font-family, monospace); word-break: break-all;">@ViewModel.TypedDataHash</MudText>
                            }
                        </MudStack>
                    </MudPaper>
                }
            }
            
            <MudPaper Class="pa-3 mt-3" Elevation="1">
                <MudStack Spacing="2">
                    <MudStack Direction="Row" AlignItems="AlignItems.Center" Spacing="1">
                        <MudText Typo="Typo.subtitle2">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.MessageLabel)</MudText>
                        @if (SignatureInfo?.IsMessageHex == true)
                        {
                            <MudChip T="string" Size="Size.Small" Color="Color.Secondary">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.HexChip)</MudChip>
                        }
                    </MudStack>

                    @if (SignatureInfo?.IsMessageHex == true && !string.IsNullOrEmpty(SignatureInfo.DecodedMessage))
                    {
                        <MudToggleIconButton @bind-Value="_showRaw" 
                                           Size="Size.Small" 
                                           Color="Color.Primary" 
                                           CheckedIcon="@Icons.Material.Filled.Code" 
                                           UncheckedIcon="@Icons.Material.Filled.Translate">
                        <ChildContent>
                            <MudTooltip Text="@(_showRaw ? Localizer.GetString(DAppSignaturePromptLocalizer.Keys.TooltipViewDecoded) : Localizer.GetString(DAppSignaturePromptLocalizer.Keys.TooltipViewRaw))" />
                        </ChildContent>
                    </MudToggleIconButton>
                    }

                    <MudTextField Value="@GetDisplayMessage()"
                                  ReadOnly="true"
                                  Lines="6"
                                  Variant="Variant.Outlined"
                                  FullWidth="true" />
                </MudStack>
            </MudPaper>
            
            @if (ViewModel.SignatureReady && !string.IsNullOrEmpty(ViewModel.SignaturePreview))
            {
                <MudPaper Class="pa-3 mt-3" Elevation="1">
                    <MudStack Spacing="2">
                        <MudText Typo="Typo.subtitle2" FontWeight="FontWeight.Bold">@Localizer.GetString(DAppSignaturePromptLocalizer.Keys.SignaturePreviewTitle)</MudText>
                        <MudTextField Value="@ViewModel.SignaturePreview"
                                      ReadOnly="true"
                                      Lines="4"
                                      Variant="Variant.Outlined"
                                      Style="font-family: var(--mud-typography-body2-font-family, monospace); word-break: break-all;"
                                      FullWidth="true" />
                            <MudStack Direction="Row" AlignItems="AlignItems.Center" Spacing="2">
                            <MudButton Variant="Variant.Outlined"
                                       Color="Color.Primary"
                                       StartIcon="@Icons.Material.Filled.ContentCopy"
                                       OnClick="CopySignatureAsync">
                                @Localizer.GetString(DAppSignaturePromptLocalizer.Keys.CopySignature)
                            </MudButton>
                        </MudStack>
                        <MudAlert Severity="Severity.Info">
                            <MudText Typo="Typo.body2">
                                @Localizer.GetString(DAppSignaturePromptLocalizer.Keys.SignatureReviewInfo)
                            </MudText>
                        </MudAlert>
                    </MudStack>
                </MudPaper>
            }

            @if (!string.IsNullOrEmpty(ViewModel.ErrorMessage))
            {
                <MudAlert Severity="Severity.Error" Class="mt-3">
                    <MudText Typo="Typo.body2">@ViewModel.ErrorMessage</MudText>
                </MudAlert>
            }

            <MudAlert Severity="Severity.Warning" Class="mt-3">
                <MudText Typo="Typo.body2">
                    @Localizer.GetString(DAppSignaturePromptLocalizer.Keys.Warning)
                </MudText>
            </MudAlert>
            </WalletFormSection>
        }
    </ChildContent>
</WalletFormLayout>

@code {
    [Parameter] public PromptRequest PromptRequest { get; set; } = null!;
    [Parameter] public EventCallback<object?> OnSigned { get; set; }
    [Parameter] public EventCallback OnRejected { get; set; }
    
    private SignaturePromptInfo? SignatureInfo => ViewModel.PromptInfo;
    private bool _showRaw;
    private string? _currentPromptId;
    
    private string GetSubtitle()
    {
        if (SignatureInfo != null && !string.IsNullOrEmpty(SignatureInfo.DAppName))
        {
            return Localizer.GetString(DAppSignaturePromptLocalizer.Keys.SubtitleFrom, SignatureInfo.DAppName);
        }
        return Localizer.GetString(DAppSignaturePromptLocalizer.Keys.SubtitleGeneric);
    }
    
    private async Task HandleSign()
    {
        if (SignatureInfo == null)
        {
            return;
        }

        if (!ViewModel.SignatureReady)
        {
            try
            {
                WalletDiagnosticsLogger.Log("BlazorPrompt", $"Signature prompt OnPrimary invoked promptId={PromptRequest?.Id}");
                await ViewModel.SignAsync();
            }
            catch (OperationCanceledException)
            {
                await HandleReject();
            }
            catch
            {
                // Error message handled in ViewModel
            }
        }
        else if (!string.IsNullOrEmpty(ViewModel.SignaturePreview))
        {
            await OnSigned.InvokeAsync(ViewModel.SignaturePreview);
        }

        StateHasChanged();
    }
    
    private async Task HandleReject()
    {
        await OnRejected.InvokeAsync();
    }

    private string GetDisplayMessage()
    {
        if (SignatureInfo == null)
        {
            return string.Empty;
        }

        if (_showRaw || string.IsNullOrEmpty(SignatureInfo.DecodedMessage))
        {
            return SignatureInfo.RawMessage;
        }

        return SignatureInfo.DecodedMessage;
    }

    protected override async Task OnParametersSetAsync()
    {
        if (PromptRequest?.Data is SignaturePromptInfo info)
        {
            if (!string.Equals(_currentPromptId, PromptRequest.Id, StringComparison.Ordinal))
            {
                _currentPromptId = PromptRequest.Id;
                await ViewModel.InitializeAsync(info);
                _showRaw = string.IsNullOrEmpty(info?.DecodedMessage);
            }
        }
        else
        {
            _currentPromptId = null;
        }
    }

    private async Task CopySignatureAsync()
    {
        if (!string.IsNullOrEmpty(ViewModel.SignaturePreview))
        {
            await JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", ViewModel.SignaturePreview);
        }
    }
}
